package com.elong.android.specialhouse.utils;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Environment;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dp.android.elong.crash.LogWriter;
import com.elong.android.specialhouse.IConfig;
import com.elong.android.specialhouse.JSONConstants;
import com.elong.android.specialhouse.R;
import com.elong.android.specialhouse.activity.AdsActivity;
import com.elong.android.specialhouse.activity.HomeActivity;
import com.elong.android.specialhouse.base.PluginBaseActivity;
import com.elong.android.specialhouse.entity.AdImageInfo;
import com.elong.android.specialhouse.entity.City;
import com.elong.android.specialhouse.ui.CustomDialogBuilder;
import com.elong.mobile.countly.support.NetUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import java.util.Random;
import java.util.Stack;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;


public class Utils {

    public final static String TAG = "Utils";
    // Device ID
    private static String s_deviceID = null;
    // DeviceID白名单
    private static final String[] DEVICEID_WHITE_LIST = {"TestWeb", "111111111111111", "11111111111111", "Unknown",
            "02:00:00:00:00:00", "w1t9hFVX6Dai3jCCUcbI4E8EbwavBHfrSUHgcozHm5k=",
            "giaLUIEbCJeuw4Qc/m4qQ1uFPFgA82Cga/5KzLQS24g=", "000000000000000", "0", "00000000000000",
            "0000000000000000", "00000000", "111111111111119", "358888888888886"};

    /**
     * 密码验证通过
     */
    public final static int VALIDATE_PWD_OK = 1;
    /**
     * 密码为空
     */
    public final static int VALIDATE_PWD_ERROR_NULL = -1;
    /**
     * 密码长度不合要求（要求：6-30位）
     */
    public final static int VALIDATE_PWD_ERROR_LENGTH = -2;

    /**
     * 密码是手机号码一部分（要求：密码不能使手机号一部分）
     */
    public final static int VALIDATE_PWD_ERROR_SAME_PHONE = -3;
    /**
     * 密码是邮箱一部分（要求：密码不能是邮箱一部分）
     */
    public final static int VALIDATE_PWD_ERROR_SAME_EMAIL = -4;

    /**
     * 密码有不合要求字符(要求：只允许有大小写字符和数字)
     */
    public final static int VALIDATE_PWD_ERROR_SAME_SPECIAL = -5;

    public final static int CONFIRMDIALOG_TYPE_YESNO = 1;
    public final static int CONFIRMDIALOG_TYPE_YESDIAL = 2;

    // 所有Activity入栈统一管理
    public static Stack<Activity> s_activitiesStack = new Stack<Activity>();


    /**
     * Loading框资源列表
     */
    public final static int[] DIALOG_IDS = {R.layout.dialog_normal, R.id.dialog_title_container, R.id.dialog_title,
            R.id.dialog_message, R.id.dialog_contentview, R.id.dialog_positive_button, R.id.dialog_negative_button,
            R.id.dialog_close_button};


    /**
     * @param address
     * @return String
     * @throws
     * @Title: retriveCityName
     * @Description: 根据定位到的城市名称匹配艺龙城市名称
     */
    public static final String retriveCityName(Context context, String address) {
        String cityName = null;
        // 遍历判断是否在艺龙城市列表
        if (!Utils.isEmptyString(address)) {
//			address = address.replace("市", "").trim();
//			ArrayList hotelCitiesData = CityDataUtil.getHotelCitiesData(context);
//
//			HashMap<String, ArrayList<String>> citiesData = (HashMap<String, ArrayList<String>>) hotelCitiesData.get(0);
//			Iterator iter = citiesData.entrySet().iterator();
//			while (iter.hasNext()) {
//				Map.Entry<String, ArrayList<String>> entry = (Map.Entry<String, ArrayList<String>>) (iter.next());
//				ArrayList<String> list = entry.getValue();
//				int len = list.size();
//				for (int i = 0; i < len; i++) {
//					String city = list.get(i).split(",")[0];
//					// 剔除城市下面的县级市,避免匹配成县级市,比如:保定市匹配成安新县（保定）
//					String mCity = city;
//					if (city.contains("(")) {
//						mCity = mCity.substring(0, city.indexOf("("));
//					}
//					if (city.contains("（")) {
//						mCity = mCity.substring(0, city.indexOf("（"));
//					}
//					if (address.contains(mCity) || mCity.contains(address)) {
//						// 城市匹配成功表示定位成功,这里的遍历会执行两次(热门城市？)，所以定位成功的回调放在这个方法外面。
//						return city.replace("市", "").trim();
//					} 
//				}
//			}

        }

        return cityName;
    }

    /**
     * @param context
     * @param cityName
     * @return String
     * @throws
     * @Title: retriveCityIdByCityName
     * @Description: 根据城市名称 精确匹配城市ID
     */
    public static final String retriveCityIdByCityName(Context context, String cityName) {
        String cityId = null;
        if (!TextUtils.isEmpty(cityName)) {
            cityName = cityName.replace("市", "").trim();
            List<City> cities = null;
            String data = FileUtils.getCitiesData(context);
            if (data != null && !TextUtils.isEmpty(data)) {
                JSONObject jo = JSONObject.parseObject(data);
                boolean isError = jo.getBooleanValue(JSONConstants.ATTR_ISERROR);
                if (!isError) {
                    cities = JSONArray.parseArray(jo.getString(JSONConstants.ATTR_ALL_CITY_LIST), City.class);
                    for (City city : cities) {
                        if (city.getCityName().startsWith(cityName)) {
                            cityId = city.getCityId();
                            return cityId;
                        }
                    }
                }
            }
        }
        return "";
    }

    /**
     * @param inputStream
     * @return Object
     * @throws
     * @Title: restoreObject
     * @Description: 从文件中读取对象
     */
    public static final Object restoreObjectByBinarySystem(InputStream inputStream) {
        InputStream fis = null;
        ObjectInputStream ois = null;
        Object object = null;
        try {
            fis = inputStream;
            ois = new ObjectInputStream(fis);
            object = ois.readObject();
            return object;

        } catch (FileNotFoundException e) {
            LogWriter.logException(TAG, "", e);
        } catch (IOException e) {
            LogWriter.logException(TAG, "", e);
        } catch (ClassNotFoundException e) {
            LogWriter.logException(TAG, "", e);
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                LogWriter.logException(TAG, "", e);
            }
        }
        return object;
    }

    /**
     * @param phoneNo
     * @param email
     * @param pwd
     * @return int
     * @throws
     * @Title: validatePwd
     * @Description: 密码验证规则（暂用于新用户注册、修改秘密的新密码、现金账户设置密码、现金账户重置密码的新密码）
     */
    public static int validatePwd(String phoneNo, String email, String pwd) {
        if (isEmptyString(pwd)) {
            return VALIDATE_PWD_ERROR_NULL;
        }
        pwd = pwd.trim();
        if (pwd.length() < 6 || pwd.length() > 30) {
            return VALIDATE_PWD_ERROR_LENGTH;
        }
        if (phoneNo != null) {
            phoneNo = phoneNo.trim();
            if (phoneNo.contains(pwd)) {
                return VALIDATE_PWD_ERROR_SAME_PHONE;
            }
        }
        if (email != null) {
            email = email.trim();
            if (email.contains(pwd)) {
                return VALIDATE_PWD_ERROR_SAME_EMAIL;
            }
        }

        char arr[] = pwd.toCharArray();
        int len = arr.length;
        for (int i = 0; i < len; i++) {
            char c = arr[i];
            if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) {
                continue;
            } else {
                return VALIDATE_PWD_ERROR_SAME_SPECIAL;
            }
        }
        return VALIDATE_PWD_OK;
    }

    /**
     * @param activity
     * @return void
     * @throws
     * @Title: pushActivity
     * @Description: 打开新页面Activity入栈
     */
    public final static void pushActivity(Activity activity) {
        if (IConfig.MANAGE_ACTIVITYSTACK_MANUALLY) {
//            Debug.u(TAG, "Push activity:" + activity.getClass().getName());
            if (s_activitiesStack != null) {
                s_activitiesStack.push(activity);
            }
        }
    }

    /**
     * @param value
     * @param option
     * @return int
     * @throws
     * @Title: convertToInt
     * @Description: 对象转化为整数数字类型
     */
    public final static int convertToInt(Object value, int option) {
        if (value == null || "".equals(value.toString().trim()) || "null".equals(value)) {
            return option;
        }
        try {
            return Integer.valueOf(value.toString());
        } catch (Exception e) {
            try {
                return Double.valueOf(value.toString()).intValue();
            } catch (Exception e1) {
                return option;
            }
        }

    }

    /**
     * @return BaseActivity
     * @throws
     * @Title: popActivity
     * @Description: 退出页面, Activity出栈
     */
    public final static Activity popActivity() {
        if (IConfig.MANAGE_ACTIVITYSTACK_MANUALLY) {
            if (!s_activitiesStack.isEmpty()) {
                return s_activitiesStack.pop();
            }
        }
        return null;
    }

    /**
     * @param context
     * @param v
     * @return void
     * @throws
     * @Title: hidenputKeyboard
     * @Description: 隐藏软键盘
     */
    public final static void hidenputKeyboard(final Context context, final View v) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);

        if (imm.isActive()) {
            if (v != null) {
                v.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        InputMethodManager imm = (InputMethodManager) context
                                .getSystemService(Context.INPUT_METHOD_SERVICE);
                        imm.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
                    }
                }, 50);
            }
        }
    }

    /**
     * @param obj
     * @return boolean
     * @throws
     * @Title: isEmptyString
     * @Description: 判断对象是否为空
     */
    public final static boolean isEmptyString(Object obj) {
        return obj == null || "".equals(obj.toString().trim()) || "null".equals(obj);
    }

    /**
     * @param value
     * @param option
     * @return double
     * @throws
     * @Title: convertToDouble
     * @Description: 把对象转换成Double类型
     */
    public final static double convertToDouble(Object value, double option) {
        if (value == null || "".equals(value.toString().trim()) || "null".equals(value)) {
            return option;
        }
        try {
            return Double.parseDouble(value.toString());
        } catch (Exception e) {
            return option;
        }

    }

    /**
     * @param path
     * @return Object
     * @throws
     * @Title: restoreObject
     * @Description: 从文件中读取对象
     */
    public static final Object restoreObject(String path) {
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        Object object = null;
        File f = new File(path);
        if (!f.exists()) {
            return null;
        }
        try {
            fis = new FileInputStream(f);
            ois = new ObjectInputStream(fis);
            object = ois.readObject();
            return object;

        } catch (FileNotFoundException e) {
            LogWriter.logException(TAG, "", e);
        } catch (IOException e) {
            LogWriter.logException(TAG, "", e);
        } catch (ClassNotFoundException e) {
            LogWriter.logException(TAG, "", e);
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                LogWriter.logException(TAG, "", e);
            }
        }
        return object;
    }

    /**
     * @param path
     * @param saveObject
     * @return void
     * @throws
     * @Title: saveObject
     * @Description: 保存对象到制定目录
     */
    public static final void saveObject(String path, Object saveObject) {
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        File f = new File(path);
        try {
            fos = new FileOutputStream(f);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(saveObject);
        } catch (FileNotFoundException e) {
            LogWriter.logException(TAG, "", e);
        } catch (IOException e) {
            LogWriter.logException(TAG, "", e);
        } finally {
            try {
                if (oos != null) {
                    oos.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                LogWriter.logException(TAG, "", e);
            }
        }
    }

    public static void handleAdvClick(PluginBaseActivity activity, AdImageInfo adImageInfo, String jumpLink) {
        Log.d(TAG, "handleAdvClick jumpLink = " + jumpLink);
        if (TextUtils.isEmpty(jumpLink)) {
            return;
        } else if (jumpLink.contains("eds.elong.com/mis/reservation/Rnotes.asp")){
            Intent intent = new Intent(activity, AdsActivity.class);
            intent.putExtra(AdsActivity.URL, jumpLink);
            intent.putExtra(JSONConstants.ATTR_TITLE, adImageInfo.title);
            activity.startActivity(intent);
        }
    }

    /**
     * @param context
     * @param title
     * @param info
     * @param listener
     * @return void
     * @throws
     * @Title: showInfo
     * @Description: 显示不可取消的，只有一个确定按钮的对话框
     */
    public static void showNoCancelInfo(Context context, String title, String info,
                                        DialogInterface.OnClickListener listener) {

        if (context instanceof Activity) {
            if (((Activity) context).isFinishing()) {
                return;
            }
        }

        CustomDialogBuilder builder = new CustomDialogBuilder(context, DIALOG_IDS, 1);
        builder.setTitle(title);
        builder.setMessage(info);
        builder.setPositiveButton(R.string.confirm, listener);
        builder.setCancelable(false);
        builder.show();
    }

    /**
     * @param context
     * @return String
     * @throws
     * @Title: getDeviceID
     * @Description: 获取手机唯一标示(根据系统DeviceID, AndroidID, MACAddress生成.为了兼容老版本的数据分析
     *, 格式为:OldDeviceID;NewDeviceID)
     */
    public static final String getDeviceID(Context context) {
        // Device ID
        String oldDeviceID = null;
        String newDeviceID = null;
        String deviceId = null;
        String androidId = null;
        String macAddress = null;
        if (!TextUtils.isEmpty(s_deviceID)) {
            return s_deviceID;
        }
        SharedPreferences prefs = context.getSharedPreferences("user_device_id", 0);
        try {
            if (prefs != null) {
                s_deviceID = prefs.getString("device_id", null);
                if (!TextUtils.isEmpty(s_deviceID)) {
                    return s_deviceID;
                }
            }

            TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

            // Device ID
            deviceId = ("" + tm.getDeviceId()).trim();
            // Android ID
            androidId = ("" + Secure.getString(context.getContentResolver(), Secure.ANDROID_ID)).trim();
            // MAC Address
            macAddress = NetUtils.getMacAddress(context);

            // --------旧版本获取DeviceID的算法 Start------------
            if (TextUtils.isEmpty(deviceId)) {
                oldDeviceID = "" + androidId;
            } else {
                oldDeviceID = deviceId;
            }
            // ---------旧版本获取DeviceID的算法 End --------------

            // ---------新版本获取DeviecID的算法 Start-------------
            if (!TextUtils.isEmpty(oldDeviceID) && !Utils.isDeviceIDInWhiteList(oldDeviceID)) {
                newDeviceID = oldDeviceID;
            }

            if (TextUtils.isEmpty(oldDeviceID) && !TextUtils.isEmpty(macAddress)) {
                newDeviceID = macAddress;
            }

            if (TextUtils.isEmpty(newDeviceID)) {
                newDeviceID = UUID.randomUUID().toString();
            }
            // ---------新版本获取DeviceID的算法 End --------------

            // 打上艺龙标记
            newDeviceID = Utils.addElongMark2DeviceID(newDeviceID);

            // 把新老算法生成的DeviceID拼凑成一个新的APP DeviceID
            s_deviceID = ("" + oldDeviceID).concat("||").concat(newDeviceID);

        } catch (Exception e) {
            String uuid = UUID.randomUUID().toString();
            s_deviceID = uuid.concat("||").concat(Utils.addElongMark2DeviceID(uuid));

        }

        prefs.edit().putString("device_id", s_deviceID).commit();
        return s_deviceID;
    }

    /**
     * @param deviceID
     * @return String
     * @Title: addElongMark2DeviceID
     * @Description: DeviceID加上艺龙标示(索引为4, 7, 10, 13的字符依次被替换为E109)
     */
    private static final String addElongMark2DeviceID(String deviceID) {

        // 如果deviceID不满15位则补全为15位
        if (TextUtils.isEmpty(deviceID) || deviceID.length() < 15) {
            for (int i = deviceID.length(); i < 15; i++) {
                deviceID = deviceID + "0";
            }
            return deviceID;
        }
        deviceID = deviceID.substring(0, 4) + "E" + deviceID.substring(5, 7) + "1" + deviceID.substring(8, 10) + "0"
                + deviceID.substring(11, 13) + "9" + deviceID.substring(14);
        return deviceID;
    }

    /**
     * @param deviceID
     * @return boolean
     * @Title: isDeviceInWhiteList
     * @Description: 判断DeviceID是否在白名单内
     */
    private static boolean isDeviceIDInWhiteList(String deviceID) {
        for (String item : DEVICEID_WHITE_LIST) {
            if (item.equals(deviceID)) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param @param context 上下文对象
     * @param @param telNumber 电话号码
     * @return void
     * @throws
     * @Title: callServerPhone
     * @Description: 拨打电话
     */
    public static void callServerPhone(Context context, String telNumber) {
        // 跑monkey，屏蔽打电话功能
        if (!IConfig.AUTO_TEST_ON) {
            try {
                Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:"
                        + telNumber));
                PackageManager packageManager = context.getPackageManager();
                List<ResolveInfo> resolveInfos = packageManager
                        .queryIntentActivities(intent,
                                PackageManager.MATCH_DEFAULT_ONLY);
                // 当intent能够找到匹配的activity的时候，启动activity，否则跳过
                if (resolveInfos != null && resolveInfos.size() > 0) {
                    context.startActivity(intent);
                } else {
                    Toast.makeText(context, "该机型不支持打电话功能！", Toast.LENGTH_LONG)
                            .show();
                }
            } catch (Exception e) {
                LogWriter.logException(TAG, LogWriter.LOG_LEVEL_NORMAL, e);
            }
        }
    }

    public static void clearActivityStack() {
        for (int i = s_activitiesStack.size(); i > 0; i--) {
            Activity act = s_activitiesStack.get(i - 1);
            act.finish();
        }
    }

    /*
    * 清除栈顶的Activity（除了房客首页TabHomeActivity）
    */
    public static void clearTopActivity() {
        for (int i = s_activitiesStack.size(); i > 0; i--) {
            Activity act = s_activitiesStack.get(i - 1);
            if ( !act.getClass().getName().equals(HomeActivity.class.getName())) {
                act.finish();
            }
        }
    }

    /**
     * @param context
     * @param view
     * @param delay
     * @return void
     * @throws
     * @Title: showInputKeyboard
     * @Description: 弹出软键盘
     */
    public static void showInputKeyboard(final Context context, final View view, int delay) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            public void run() {
                InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
            }
        }, delay);
    }

    public static boolean isAppRunning(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(100);
        for (ActivityManager.RunningTaskInfo info : tasks) {
            if (info.topActivity.getPackageName().equals("com.elong.android.youfang") && info.baseActivity.getPackageName().equals("com.elong.android.youfang")) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取versionName
     * @param context
     * @return
     */
    public static String getVersionName(Context context) {
        String version = "";
        PackageManager pm = context.getPackageManager();
        try {
            PackageInfo info = pm.getPackageInfo(context.getPackageName(), 0);
            version = info.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return version;
    }

    /**
     * 获取versionCode
     * @param context
     * @return
     */
    public static int getVersionCode(Context context) {
        int versionCode = -1 ;
        try {
            versionCode = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return versionCode ;
    }

    /**
     *
     * @Title: getPushIDFromLocal
     * @Description: 获取本地保存的PushID(被URLEncode过)
     * @return String
     * @throws
     */
    public static final String getPushIDFromLocal() {
        String fileName = getSDPath() + "/PushId.txt";
        String pushID = null;
        File file = new File(fileName);
        if (!file.exists()) {
            return null;
        }

        try {
            // 打开一个写文件器，构造函数中的第二个参数true表示以追加形式写文件
            FileReader reader = new FileReader(fileName);
            BufferedReader br = new BufferedReader(reader);
            pushID = br.readLine();
            br.close();
            reader.close();
        } catch (Exception e) {
//            Debug.u(TAG, e.getMessage());
        }

        return pushID;
    }
    public static String getSDPath() {
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
        if (sdCardExist) {
            sdDir = Environment.getExternalStorageDirectory();// 获取跟目录
            return sdDir.toString();
        } else {
            return Environment.getDataDirectory().getPath();
        }

    }

    /**
     * 生成轨迹号
     *
     * @return
     */
    public static String generateTraceId() {
        return Long.toString(Math.abs(new Random().nextLong()));
    }
}